<script setup lang="ts">
import {ref, reactive, onMounted, nextTick} from 'vue';
import * as THREE from 'three';
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {OBJLoader} from "three/examples/jsm/loaders/OBJLoader";
import MTLLoader from 'three-mtl-loader';
import * as TWEEN from '@tweenjs/tween.js';
import {CSS2DRenderer, CSS2DObject} from "three/examples/jsm/renderers/CSS2DRenderer";
import * as echarts from 'echarts';
import moment from 'moment';
//创建一个场景对象
const scene = new THREE.Scene()
scene.background = new THREE.Color('#080C13');
//创建CSS2DRenderer
const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0';
labelRenderer.domElement.style.pointerEvents = 'none';
/**
 * 相机设置
 */
//窗口宽度
const width = window.innerWidth;
//窗口高度
const height = window.innerHeight;
//窗口宽高比
const k = width / height;
//三维场景显示范围控制系数，系数越大，显示的范围越大
const s = 200;
//创建相机对象
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
//设置相机位置
/**
 * 相机中心点
 */
const cameraCenterPoint = ref({
  x: 0,
  y: 0,
  z: 0
})
/**
 * 相机角度
 */
const cameraPoint = ref({
  x: 0,
  y: 200,
  z: 200
})
camera.position.set(cameraPoint.value.x, cameraPoint.value.y, cameraPoint.value.z);
//设置相机方向(指向的场景对象)
camera.lookAt(scene.position);
/**
 * 光源设置
 */
//新建点光源(常用光源分为点光源和环境光，点光源的效果类似灯泡，环境光的效果类似白天的太阳光)
const point = new THREE.PointLight(0xffffff);
//设置点光源的位置
point.position.set(400, 200, 300);
//将点光源添加到场景中
scene.add(point);
const objWidth = 30;

/**
 * 创建渲染器对象
 */
//创建渲染器对象(渲染要等所有东西都加进去再渲染场景，创建和3D模型和光源没有先后顺序)
const renderer = new THREE.WebGLRenderer();
//循环渲染
const render = () => {
  //执行渲染操作   指定场景、相机作为参数
  renderer.render(scene, camera);
  labelRenderer.render(scene, camera);
  // 使用 requestAnimationFrame 函数安排下一次渲染
  requestAnimationFrame(render);
}
/**
 * 开启场景镜头控制
 */
const controls_ = new OrbitControls(camera, renderer.domElement);

const controls = () => {
  controls_.addEventListener('change', function () {
    // 浏览器控制台查看相机位置变化
    // console.log('camera.position', camera.position);
  });
  controls_.enablePan = true;
  controls_.minZoom = 0.1;
  controls_.maxZoom = 3;
}

/**
 * 加载锅炉模型
 */
const loadDeviceObj = () => {
  //创建一个用于加载 .obj 资源的加载器
  const mtlLoader = new MTLLoader();
  const OBJLoader_ = new OBJLoader();
  // mtlLoader.load('/储罐3.mtl', materials => {
  //   materials.preload();
  //   OBJLoader_.setMaterials(materials).load('储罐3.obj', function (obj: any) {
  //     let mesh = obj.children[0];
  //     mesh.rotateZ(Math.PI);
  //     mesh.translateY(-100);
  //     mesh.translateZ(0);
  //     mesh.scale.x = 5;
  //     mesh.scale.y = 10;
  //     mesh.scale.z = 5;
  //     mesh['data'] = {type: 'device'};
  //     scene.add(mesh);
  //   })
  // })
  OBJLoader_.load('/002.obj', function (obj: any) {
    let mesh = obj.children[0];
    mesh.rotateZ(Math.PI);
    mesh.translateY(-100);
    mesh.translateZ(0);
    mesh.scale.x = 5;
    mesh.scale.y = 10;
    mesh.scale.z = 5;
    mesh['data'] = {type: 'device'};
    scene.add(mesh);
  });
}

const animate = () => {
  // 切换相机位置必须要在这里执行这一步
  TWEEN.update();
  renderer.render(scene, camera);
  labelRenderer.render(scene, camera);
  requestAnimationFrame(animate);
}
/**
 * 相机平滑过度
 */
const animateCamera = (toPoint: any) => {
  const c = cameraCenterPoint.value;
  const tween = new TWEEN.Tween({
    x1: cameraPoint.value.x, // 相机x
    y1: cameraPoint.value.y, // 相机y
    z1: cameraPoint.value.z, // 相机z
    x2: c.x, // 控制点的中心点x
    y2: c.y, // 控制点的中心点y
    z2: c.z  // 控制点的中心点z
  }).to({
    x1: toPoint.x,
    y1: toPoint.y,
    z1: toPoint.z,
    x2: c.x,
    y2: c.y,
    z2: c.z
  }, 1000)
      .easing(TWEEN.Easing.Cubic.InOut)
      .onUpdate(function (object) {
        camera.position.set(object.x1, object.y1, object.z1)
        controls_.target.x = object.x2;
        controls_.target.y = object.y2;
        controls_.target.z = object.z2;
        controls_.update();
      }).start();
  animate();
  cameraPoint.value = toPoint;
}
const lastMesh = ref({});
const params = reactive({
  left: 0,
  top: 0,
  S: 0
})
/**
 * 模型点击选择
 * @param event
 */
renderer.localClippingEnabled = true;
const PlaneArr = [new THREE.Plane(new THREE.Vector3(-1, 0, -2), 1), new THREE.Plane(new THREE.Vector3(1, 0, -2), 0)];
const choose = (event: any) => {
  if (!_.isEmpty(lastMesh.value)) {
    lastMesh.value.material.clippingPlanes = null;
  }
  const Sx = event.clientX;
  const Sy = event.clientY;
  params.left = Sx + 20;
  params.top = Sy + 20;
  const x = (Sx / window.innerWidth) * 2 - 1;
  const y = -(Sy / window.innerHeight) * 2 + 1;
  const raycaster = new THREE.Raycaster();
  raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
  const intersects = raycaster.intersectObjects(scene.children, true);
  if (intersects.length > 0) {
    const mesh = intersects[0].object;
    scene.updateMatrixWorld(true);
    const worldPosition = new THREE.Vector3();
    mesh.getWorldPosition(worldPosition);
    lastMesh.value = mesh;
    PlaneArr[0].constant = worldPosition.x;
    PlaneArr[1].constant = worldPosition.z;
    mesh.material.clipIntersection = true;
    mesh.material.clippingPlanes = PlaneArr;
  }
}
// addEventListener('click', choose);

/**
 * 创建位号显示
 */
const createCSS2DObject = (point: any, text: string) => {
  let el = document.createElement('div');
  el.innerHTML = `<div style="position:relative;width: 100px;white-space: nowrap;">
        <div style="position: absolute;top:-25px;left:20px;width:100px;color:#000000;">
        ${text}
        </div>
        <div style="position: absolute;top:0;left:0;">
          <img src="/Three/images/line/line.png">
        </div>
      </div>`
  el.cloneNode(true);
  el.style.pointerEvents = 'none';
  const css2DObject = new CSS2DObject(el);
  css2DObject.position.set(point.x, point.y, point.z);
  scene.add(css2DObject)
}

const createTabNumber = () => {
  createCSS2DObject({x: 67, y: -20, z: 0}, 'T12161 - 463°C');
  createCSS2DObject({x: 67, y: -45, z: 0}, 'T12161 - 501°C');
  createCSS2DObject({x: 67, y: -70, z: 0}, 'T12161 - 537°C');
  createCSS2DObject({x: objWidth / 2 + 80, y: 20, z: -20}, 'RC2101C - 528.3Mpa');
}

const barInit = () => {
  // 基于准备好的dom，初始化echarts实例
  const myChart = echarts.init(document.getElementById('bar'));
// 绘制图表
  myChart.setOption({
    grid: {
      left: 40,
      right: 0,
      bottom: 20
    },
    tooltip: {},
    legend: {
      right: 10,
      textStyle: {
        color: '#ffffff'
      }
    },
    xAxis: {
      data: ['2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06', '2024-07', '2024-08'],
      axisTick: {
        show: false // 这里设置x轴的刻度线不显示
      },
      axisLabel: {
        textStyle: {
          color: '#ffffff'
        }
      }
    },
    yAxis: {
      axisLabel: {
        textStyle: {
          color: '#ffffff'
        }
      },
      splitLine: {
        lineStyle: {
          color: '#2F3B5D',
          type: 'dashed'
        }
      }
    },
    series: [
      {
        name: '示例',
        type: 'bar',
        barWidth: 14,
        itemStyle: {
          // 为每个柱子设置渐变色
          color: new echarts.graphic.LinearGradient(
              0, 0, 0, 1, // 这四个参数分别表示渐变的起点 (x1, y1) 与终点 (x2, y2)
              [
                {offset: 0, color: '#351FFF'},   // 0% 处的颜色
                {offset: 1, color: '#206FFF'}   // 100% 处的颜色
              ]
          )
        },
        data: [1000, 300, 70, 370, 800, 510, 710, 210]
      }
    ]
  });
}
const barInit2 = () => {
  // 基于准备好的dom，初始化echarts实例
  const myChart = echarts.init(document.getElementById('bar2'));
// 绘制图表
  myChart.setOption({
    grid: {
      left: 50,
      right: 0,
      bottom: 20
    },
    tooltip: {},
    legend: {
      right: 10,
      textStyle: {
        color: '#ffffff'
      }
    },
    xAxis: {
      data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
      axisTick: {
        show: false // 这里设置x轴的刻度线不显示
      },
      axisLabel: {
        textStyle: {
          color: '#ffffff'
        }
      },
      axisLine: {
        lineStyle: {
          color: '#ffffff'
        }
      }
    },
    yAxis: {
      axisLabel: {
        textStyle: {
          color: '#ffffff'
        }
      },
      splitLine: {
        lineStyle: {
          color: '#2F3B5D',
          type: 'dashed'
        }
      }
    },
    series: [
      {
        name: '平均值',
        type: 'bar',
        barWidth: 14,
        itemStyle: {
          // 为每个柱子设置渐变色
          color: new echarts.graphic.LinearGradient(
              0, 0, 0, 1, // 这四个参数分别表示渐变的起点 (x1, y1) 与终点 (x2, y2)
              [
                {offset: 0, color: '#34DCFE'},   // 0% 处的颜色
                {offset: 1, color: '#00F0FF'}   // 100% 处的颜色
              ]
          )
        },
        data: [2500, 3000, 2100, 1800, 800, 5100, 2800, 4650, 5650, 1650, 3650, 6650]
      },
      {
        name: '最低值',
        type: 'bar',
        barWidth: 14,
        itemStyle: {
          // 为每个柱子设置渐变色
          color: new echarts.graphic.LinearGradient(
              0, 0, 0, 1, // 这四个参数分别表示渐变的起点 (x1, y1) 与终点 (x2, y2)
              [
                {offset: 0, color: '#40B3FF'},   // 0% 处的颜色
                {offset: 1, color: '#546BFF'}   // 100% 处的颜色
              ]
          )
        },
        data: [2800, 4650, 5650, 1650, 3650, 6650, 2500, 3000, 2100, 1800, 800, 5100]
      },
      {
        name: '销售值',
        type: 'line',
        smooth: true,
        lineStyle: {
          color: '#31FBFB'
        },
        markLine: {
          lineStyle: {
            color: '#AA6598'
          },
          data: [
            {
              type: 'average',
              name: '平均值'
            }
          ],
          symbol: ['none', 'none'],
          label: {
            position: 'end',
            formatter: '平均值: ' + '{c}'
          }
        },
        data: [1800, 5650, 2650, 3650, 4650, 3650, 4500, 1000, 5100, 9800, 1800, 1100]
      },
      {
        type: 'custom',
        zlevel: -1,
        itemStyle: {
          color: 'rgba(51, 154, 240,0.2)'
        },
        tooltip: {
          show: false
        },
        renderItem: function (params, api) {
          const start = api.coord([api.value(0)]);
          const width = (params.coordSys.width / 12) * 0.8;
          return {
            type: 'rect',
            shape: {
              // 相对左上角坐标
              x: start[0] - width / 2,
              y: params.coordSys.y,
              width: width,
              height: params.coordSys.height,
            },
            style: api.style()
          };
        },
        data: [1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
      }
    ]
  });
}

const gaugeInit = (id, color, formatter, fontSize) => {
  const myChart = echarts.init(document.getElementById(id));
// 绘制图表
  myChart.setOption({
    tooltip: {
      formatter: '{a} <br/>{b} : {c}%'
    },
    series: [
      {
        name: 'Pressure',
        type: 'gauge',
        progress: {
          show: true,
          itemStyle: {
            color: new echarts.graphic.LinearGradient(
                0, 0, 0, 1, // 这四个参数分别表示渐变的起点 (x1, y1) 与终点 (x2, y2)
                [
                  {offset: 0, color: color[0]},   // 0% 处的颜色
                  {offset: 1, color: color[1]}   // 100% 处的颜色
                ]
            ),
            borderColor: '#17C4D7',
            borderWidth: 1
          }
        },
        splitLine: {
          show: false,
          distance: 0,
          length: 10
        },
        axisTick: {
          show: false
        },
        axisLabel: {
          show: false
        },
        pointer: {
          show: false
        },
        detail: {
          color: '#FFFFFF',
          fontSize: fontSize,
          valueAnimation: true,
          formatter: formatter,
          offsetCenter: [0, '5%'],
        },
        data: [
          {
            value: 50
          }
        ]
      }
    ]
  });
}

const weekday = ['一', '二', '三', '四', '五', '六', '日']
const timeInfo = ref({});
const getTime = () => {
  const date = moment();
  return {
    year: date.year(),
    month: date.month() + 1,
    date: date.date(),
    hour: date.hour() < 10 ? '0' + date.hour() : date.hour(),
    minute: date.minute() < 10 ? '0' + date.minute() : date.minute(),
    second: date.second() < 10 ? '0' + date.second() : date.second(),
    weekday: weekday[date.weekday() - 1]
  }
}

const refreshTime = () => {
  timeInfo.value = getTime();
  setInterval(() => {
    timeInfo.value = getTime();
  }, 1000)
}
onMounted(() => {
  refreshTime();
  nextTick(() => {
    setTimeout(() => {
      barInit();
      barInit2();
      gaugeInit('gauge', ['#66FFFF', '#00F0FF'], '{value}次', 12);
      gaugeInit('gauge2', ['#5AFEA3', '#66FFFF'], '{value}%\n888.2万', 18);
      gaugeInit('gauge3', ['#383AF9', '#7E7DF5'], '{value}%\n888.2万', 18);
    }, 0)
    loadDeviceObj();
    // createTabNumber();
    //设置渲染区域尺寸(设置的是整个屏幕的长度和宽度
    renderer.setSize(width, height);
    //设置渲染的背景色
    renderer.setClearColor(0xb9d3ff, 1);
    //body元素中插入canvas对象，也可以在页面中添加div，并加上id，通过id指定在某个div中渲染
    const container = document.getElementById("three");
    container?.appendChild(renderer.domElement);
    container?.appendChild(labelRenderer.domElement);
    //渲染
    render();
    //开启镜头旋转
    controls();
  })
})
</script>

<template>
  <div class="three-body w-full h-full">
    <!--    <div class="handle">-->
    <!--      <el-button-group class="ml-4">-->
    <!--        <el-button type="primary" @click="animateCamera({x:0,y:0,z:200})">正面视角</el-button>-->
    <!--        <el-button type="primary" @click="animateCamera({x:0,y:200,z:200})">斜视视角</el-button>-->
    <!--        <el-button type="primary" @click="animateCamera({x:0,y:200,z:0})">俯视视角</el-button>-->
    <!--      </el-button-group>-->
    <!--    </div>-->
    <div id="three" class="w-full h-full"></div>
  </div>
  <div class="data-body w-full h-full flex flex-col">
    <div class="top">
      <img src="/src/assets/top.png">
      <div class="wrapper w-full h-full flex">
        <div class="left flex items-center w-400px">
          <div class="mt-10px">渤化化工</div>
        </div>
        <div class="flex-1 center justify-center flex items-center">
          <div class="mb-10px">可视化数据分析</div>
        </div>
        <div class="right justify-end flex items-center w-400px">
          <div class="time mr-10px mt-10px w-135px">{{ timeInfo.hour }}:{{ timeInfo.minute }}:{{ timeInfo.second }}
          </div>
          <div class="mr-10px mt-10px">
            <div class="first flex justify-end">{{ timeInfo.year }}年{{ timeInfo.month }}月{{ timeInfo.date }}日
              星期{{ timeInfo.weekday }}
            </div>
            <div class="second mt-10px">最新数据更新于2024.08.10</div>
          </div>
        </div>
      </div>
    </div>
    <div class="flex-1 flex flex-col mb-40px">
      <div class="flex-1 ml-55px mr-55px mt-20px flex box-border">
        <div class="w-1/4 flex flex-col">
          <div class="item-top h-45px">
            <img src="/src/assets/item-top.png">
            <div class="title flex items-center">平稳率</div>
          </div>
          <div class="flex-1 pt-24px">
            <div class="w-full h-full chart">
              <div class="chart-wrapper pt-22px pr-25px pb-22px pl-25px">
                <div class="w-full h-full flex flex-col">
                  <div class="chart-wrapper-title">数值</div>
                  <div class="flex-1" id="bar"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="flex-1 ml-25px mr-25px"></div>
        <div class="w-1/4 flex flex-col">
          <div class="item-top h-45px">
            <img src="/src/assets/item-top.png">
            <div class="title flex items-center">软仪表在线率</div>
          </div>
          <div class="flex-1 pt-24px">
            <div class="w-full h-full chart">
              <div class="chart-wrapper pt-22px pr-25px pb-22px pl-25px">
                <div class="w-full h-full flex flex-col">
                  <div class="chart-wrapper-title">数值</div>
                  <div class="flex-1 flex items-center justify-center">
                    <div class="count-item mr-20px">
                      <div class="count-number">63,935</div>
                      <img src="/src/assets/count.png">
                      <div class="text-center" style="color:#ffffff">一线</div>
                    </div>
                    <div class="count-item">
                      <div class="count-number">63,935</div>
                      <img src="/src/assets/count.png">
                      <div class="text-center" style="color:#ffffff">二线</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="flex-1 ml-55px mr-55px mt-20px flex box-border">
        <div class="w-1/4 flex flex-col">
          <div class="item-top h-45px">
            <img src="/src/assets/item-top.png">
            <div class="title flex items-center">投用率</div>
          </div>
          <div class="flex-1 pt-24px">
            <div class="w-full h-full chart">
              <div class="chart-wrapper p-25px flex flex-col">
                <div class="flex-1 flex">
                  <div class="flex-1 flex flex-col guage1-item">
                    <div class="flex-1" id="gauge"></div>
                    <div class="text-center pb-20px">
                      <p class="title1">一线总类</p>
                      <p class="title2 mt-2px">已完成45%</p>
                    </div>
                  </div>
                  <div class="flex-1"></div>
                  <div class="flex-1"></div>
                </div>
                <div class="flex-1"></div>
              </div>
            </div>
          </div>
        </div>
        <div class="flex-1 ml-25px mr-25px flex flex-col">
          <div class="item-top h-45px">
            <img src="/src/assets/item-top.png">
            <div class="title flex items-center">自控率</div>
          </div>
          <div class="flex-1 pt-24px">
            <div class="w-full h-full chart chart-center">
              <div class="jiantou1">
                <img src="/src/assets/jt1.png">
              </div>
              <div class="jiantou2">
                <img src="/src/assets/jt2.png">
              </div>
              <div class="chart-wrapper">
                <img src="/src/assets/item-bg2.png">
              </div>
              <div class="chart-wrapper pb-20px p-20px" id="bar2">
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/4 flex flex-col">
          <div class="item-top h-45px">
            <img src="/src/assets/item-top.png">
            <div class="title flex items-center">自控率</div>
          </div>
          <div class="flex-1 pt-24px">
            <div class="w-full h-full chart">
              <div class="chart-wrapper p-25px flex">
                <div class="flex-1 flex flex-col guage2-item">
                  <div class="flex-1 gauge-item">
                    <div class="w-full h-full" style="position: relative">
                      <div class="w-full h-full" style="position: absolute;left:0;top:0;">
                        <div id="gauge2" class="w-full h-full" style="position:relative;"></div>
                      </div>
                    </div>
                  </div>
                  <div class="text-center pb-20px">
                    <p class="title1">一线</p>
                  </div>
                </div>
                <div class="flex-1 flex flex-col guage2-item">
                  <div class="flex-1 gauge-item">
                    <div class="w-full h-full" style="position: relative">
                      <div class="w-full h-full" style="position: absolute;left:0;top:0;">
                        <div id="gauge3" class="w-full h-full"></div>
                      </div>
                    </div>
                  </div>
                  <div class="text-center pb-20px">
                    <p class="title1">二线</p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.data-body {
  position: absolute;
  top: 0;
  left: 0;

  .top {
    position: relative;

    img {
      width: 100%;
    }

    .wrapper {
      position: absolute;
      top: 0;
      left: 0;

      .left {
        padding-left: 60px;
        font-family: PangMenZhengDao;
        font-size: 32px;
        color: #D8F0FF;
        line-height: 34px;
        text-shadow: 0px 0px 12px #3F91D8;
        text-stroke: 1px #3F91D8;
        text-align: left;
        font-style: normal;
        text-transform: none;
        -webkit-text-stroke: 1px #3F91D8;
      }

      .center {
        font-family: PangMenZhengDao;
        font-size: 42px;
        color: #FFFFFF;
        line-height: 45px;
        letter-spacing: 9px;
        text-align: right;
        font-style: normal;
        text-transform: none;
      }

      .right {
        .first {
          font-family: PingFang-SC, PingFang-SC;
          font-weight: 400;
          font-size: 16px;
          color: #C0EAFF;
          line-height: 22px;
          text-align: left;
          font-style: normal;
          text-transform: none;
        }

        .second {
          font-family: PingFang-SC, PingFang-SC;
          font-weight: 400;
          font-size: 14px;
          color: rgba(255, 255, 255, 0.6);
          line-height: 21px;
          letter-spacing: 1px;
          text-align: left;
          font-style: normal;
          text-transform: none;
        }

        .time {
          font-family: YouSheBiaoTiHei;
          font-size: 32px;
          color: #C0EAFF;
          line-height: 42px;
          letter-spacing: 1px;
          text-align: left;
          font-style: normal;
          text-transform: none;
        }
      }
    }
  }

  .item-top {
    position: relative;

    .title {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      padding-left: 70px;
      font-family: PangMenZhengDao;
      font-size: 22px;
      color: #FFFFFF;
      line-height: 23px;
      letter-spacing: 3px;
      text-shadow: 0px 0px 8px #159AFF;
      text-align: left;
      font-style: normal;
      text-transform: none;
    }
  }

  .chart {
    background-image: url('@/assets/item-bg.png');
    background-size: 100% 100%;

    &.chart-center {
      background-image: none;
    }

    img {
      width: 100%;
      height: 100%;
    }

    position: relative;

    .chart-wrapper {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;

      .chart-wrapper-title {
        font-family: PingFang-SC, PingFang-SC;
        font-weight: 400;
        font-size: 18px;
        color: #FFFFFF;
        line-height: 26px;
        text-align: justify;
        font-style: normal;
        text-transform: none;
      }

      .count-item {
        position: relative;

        .count-number {
          width: 100%;
          position: absolute;
          text-align: center;
          padding-top: 50px;
          font-family: PangMenZhengDao;
          font-weight: bold;
          font-size: 26px;
          color: #FFFFFF;
          line-height: 30px;
          text-shadow: 0px 1px 4px rgba(7, 44, 137, 0.5);
          font-style: normal;
          background: linear-gradient(90deg, #FFFFFF 0%, #D4F1FF 80%, #3CC1FF 100%);
          /* 使用 blend-mode 实现文本颜色与背景渐变颜色的混合 */
          -webkit-background-clip: text;
          background-clip: text;
          /* 使用 color 作为遮罩，实际看到的是背景渐变 */
          -webkit-text-fill-color: transparent;
          text-fill-color: transparent;
          /* 防止文本阴影遮挡背景渐变 */
          -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
        }
      }

      .guage1-item {
        position: relative;

        #gauge {
          background-image: url('@/assets/gauge1.png');
          background-size: contain; /* 背景图片高度自适应 */
          background-position: center; /* 背景图片居中 */
          background-repeat: no-repeat;
          background-clip: border-box;
        }

        .title1 {
          font-family: SourceHanSansCN, SourceHanSansCN;
          font-weight: bold;
          font-size: 16px;
          color: #00E1FF;
          line-height: 18px;
          font-style: normal;
        }

        .title2 {
          font-family: SourceHanSansCN, SourceHanSansCN;
          font-weight: 400;
          font-size: 12px;
          color: #CBCED4;
          line-height: 15px;
          font-style: normal;
        }
      }

      .guage2-item {
        position: relative;

        .gauge-item {
          background-image: url('@/assets/gauge2.png');
          background-size: contain; /* 背景图片高度自适应 */
          background-position: center; /* 背景图片居中 */
          background-repeat: no-repeat;
          background-clip: border-box;
        }

        .title1 {
          font-family: SourceHanSansCN, SourceHanSansCN;
          font-weight: bold;
          font-size: 16px;
          color: #FFFFFF;
          line-height: 18px;
          font-style: normal;
        }
      }
    }

    .jiantou1 {
      width: 22px;
      position: absolute;
      right: 0;
      bottom: 0;
    }

    .jiantou2 {
      width: 22px;
      position: absolute;
      left: 0;
      top: 0;
    }
  }
}

.three-body {
  position: relative;

  .handle {
    position: absolute;
    top: 10px;
    right: 20px;
  }
}
</style>
<style lang="scss">
* {
  box-sizing: border-box;
}

body {
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;

  #app {
    width: 100vw;
    height: 100vh;
    margin: 0;
    padding: 0;
  }
}
</style>